home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * render -
- * Help use the graphics library to generate high resolution
- * rendered images.
- *
- * Paul Haeberli - 1988
- */
- #include "gl.h"
- #include "glmode.h"
- #include "values.h"
- #include "math.h"
- #include "image.h"
- #include "vect.h"
- #include "izoom.h"
-
- static setvp();
- static zoomadd();
- static makename();
- static makeframe();
-
- static int orthomode = 0;
- static float rl = -0.2;
- static float rr = 0.2;
- static float rb = -0.2;
- static float rt = 0.2;
- static float rnear = 1.0;
- static float rfar = 100.0;
- static float raspect = 1.0;
- static float rfocus = 5.0;
- static float raperture = 1.0;
- static float rpixeldiameter = 1.0;
- static float ox1, ox2, oy1, oy2, oz1, oz2;
- static int vpxsize, vpysize;
-
- /*
- * general rendering stuff follows
- *
- *
- */
- renderperspective(fov,aspect,near,far)
- int fov;
- float aspect, near, far;
- {
- renderfperspective(fov/10.0,aspect,near,far);
- }
-
- renderfperspective(fov,aspect,near,far)
- float fov;
- float aspect, near, far;
- {
-
- float tanval;
-
- tanval = near*tan(fov*M_PI/360.0);
- renderwindow(-tanval*aspect,tanval*aspect,-tanval,tanval,near,far);
- }
-
- renderwindow(l,r,b,t,near,far)
- float l,r,b,t,near,far;
- {
- rl = l;
- rr = r;
- rb = b;
- rt = t;
- rnear = near;
- rfar = far;
- raspect = (r-l)/(t-b);
- orthomode = 0;
- restorewindow();
- }
-
- getrenderwindow(l,r,b,t,near,far)
- float *l,*r,*b,*t,*near,*far;
- {
- *l = rl;
- *r = rr;
- *b = rb;
- *t = rt;
- *near = rnear;
- *far = rfar;
- }
-
- renderortho(x1,x2,y1,y2,z1,z2)
- float x1,x2,y1,y2,z1,z2;
- {
- ortho(x1,x2,y1,y2,z1,z2);
- ox1 = x1;
- ox2 = x2;
- oy1 = y1;
- oy2 = y2;
- oz1 = z1;
- oz2 = z2;
- orthomode = 1;
- }
-
- set35mmlens(focallength)
- float focallength;
- {
- float dx, dy;
-
- dx = 18.0*(rnear/focallength);
- dy = 12.0*(rnear/focallength);
- renderwindow(-dx,dx,-dy,dy,rnear,rfar);
- }
-
- setzclip(near,far)
- float near, far;
- {
- rnear = near;
- rfar = far;
- restorewindow();
- }
-
- setfocus(focus)
- float focus;
- {
- rfocus = focus;
- }
-
- setaperture(aper)
- float aper;
- {
- raperture = aper;
- }
-
- setpixeldiameter(d)
- float d;
- {
- rpixeldiameter = d;
- }
-
- setlensangle(angle)
- float angle;
- {
- renderfperspective(angle,raspect,rnear,rfar);
- }
-
- static float wpixdx, wpixdy;
- static float weyedx, weyedy;
- static float wfocus;
-
- accset(pixdx,pixdy,eyedx,eyedy)
- float pixdx,pixdy,eyedx,eyedy;
- {
- wpixdx = pixdx*rpixeldiameter;
- wpixdy = pixdy*rpixeldiameter;
- weyedx = eyedx*raperture;
- weyedy = eyedy*raperture;
- restorewindow();
- }
-
- restorewindow()
- {
- accwindow(rl,rr,rb,rt,rnear,rfar,wpixdx,wpixdy,weyedx,weyedy,rfocus);
- }
-
- /*
- * accwindow -
- * Just like the window command, but lets you do
- * sub-pixel positioning, depth of field, and stereo,
- *
- * Paul Haeberli - 1989
- *
- */
- accwindow(l,r,b,t,near,far,pixdx,pixdy,eyedx,eyedy,focus)
- float l, r, b, t, near, far;
- float pixdx, pixdy, eyedx, eyedy, focus;
- {
- short vx1, vx2, vy1, vy2;
- float xwsize, ywsize;
- float dx, dy;
- int xpixels, ypixels;
-
- if(focus<0.0)
- focus = -focus;
- getviewport(&vx1,&vx2,&vy1,&vy2);
- xpixels = vx2-vx1+1;
- ypixels = vy2-vy1+1;
- xwsize = r-l;
- ywsize = t-b;
- dx = -(pixdx*xwsize/xpixels+eyedx*near/focus);
- dy = -(pixdy*ywsize/ypixels+eyedy*near/focus);
- mmode(MPROJECTION);
- window(l+dx,r+dx,b+dy,t+dy,near,far);
- translate(-eyedx,-eyedy,0.0);
- mmode(MVIEWING);
- }
-
- accortho()
- {
- fprintf(stderr,"accortho: not implemented\n");
- }
-
- vpsize(xsize,ysize)
- int xsize, ysize;
- {
- vpxsize = xsize;
- vpysize = ysize;
- }
-
- getvpsize(xsize,ysize)
- int *xsize, *ysize;
- {
- short vx1, vx2, vy1, vy2;
-
- getviewport(&vx1,&vx2,&vy1,&vy2);
- *xsize = vx2-vx1+1;
- *ysize = vy2-vy1+1;
- }
-
- clipvol(x,y,z,p)
- int x, y, z;
- vect *p;
- {
- float zp;
- long near, far;
-
- getzviewport(&near,&far);
- p->x = 2.0*(x+0.5)/vpxsize - 1.0;
- p->y = 2.0*(y+0.5)/vpysize - 1.0;
- p->z = 2.0*((float)(z-near))/(far-near) - 1.0;
- }
-
-
- /*
- * Various render drawing functions
- *
- *
- */
- rendertoscreen(drawfunc)
- int (*drawfunc)();
- {
- mmode(MPROJECTION);
- if(orthomode)
- ortho(ox1,ox2,oy1,oy2,oz1,oz2);
- else
- window(rl,rr,rb,rt,rnear,rfar);
- mmode(MVIEWING);
- pushmatrix();
- (drawfunc)();
- popmatrix();
- }
-
- renderstereo(drawfunc)
- int (*drawfunc)();
- {
- }
-
- rendersubpix(drawfunc,xoffset,yoffset)
- int (*drawfunc)();
- float xoffset, yoffset;
- {
- mmode(MPROJECTION);
- if(orthomode)
- accortho(ox1,ox2,oy1,oy2,oz1,oz2,xoffset,yoffset,0.0,0.0,1.0);
- else
- accset(xoffset,yoffset,0.0,0.0);
- mmode(MVIEWING);
- pushmatrix();
- (drawfunc)();
- popmatrix();
- }
-
- shiftrender(drawfunc,xshift,yshift)
- int (*drawfunc)();
- float xshift, yshift;
- {
- if(orthomode) {
- fprintf(stderr,"shift render: huh?\n");
- exit(1);
- } else {
- accset(0.0,0.0,xshift,yshift);
- }
- pushmatrix();
- (drawfunc)();
- popmatrix();
- }
-
- subshiftrender(drawfunc,xsub,ysub,xshift,yshift)
- int (*drawfunc)();
- float xsub, ysub, xshift, yshift;
- {
- mmode(MPROJECTION);
- if(orthomode) {
- fprintf(stderr,"shift render: huh?\n");
- exit(1);
- } else {
- accset(xsub,ysub,xshift,yshift);
- }
- mmode(MVIEWING);
- pushmatrix();
- (drawfunc)();
- popmatrix();
- }
-
- rendertofile(drawfunc,outname,xsize,ysize)
- int (*drawfunc)();
- char *outname;
- int xsize, ysize;
- {
- char filename[40];
- char assemblecmd[4069];
- char removecmd[4069];
- char syscmd[4069];
- long xdraw, ydraw;
- int x, y, nx, ny;
- int fno;
-
- getsize(&xdraw,&ydraw);
- reshapeviewport();
- if(xsize<=xdraw && ysize<=ydraw) {
- makeframe(0,0,xdraw,ydraw,xsize,ysize);
- pushmatrix();
- (drawfunc)();
- popmatrix();
- savergbwindow("temp000.rgb");
- sprintf(syscmd,"subimg temp000.rgb %s 0 %d 0 %d",outname,xsize-1,ysize-1);
- system(syscmd);
- system("rm temp000.rgb");
- } else {
- nx = 1+((xsize-1)/xdraw);
- ny = 1+((ysize-1)/ydraw);
- fno = 0;
- sprintf(assemblecmd,"assemble %d %d temp1.rgb ",nx,ny);
- sprintf(removecmd,"rm ");
- for(y=0; y<ny; y++) {
- for(x=0; x<nx; x++) {
- makeframe(x,y,xdraw,ydraw,xsize,ysize);
- pushmatrix();
- (drawfunc)();
- popmatrix();
- makename(fno++,filename);
- strcat(assemblecmd,filename);
- strcat(assemblecmd," ");
- strcat(removecmd,filename);
- strcat(removecmd," ");
- savergbwindow(filename);
- }
- }
- system(assemblecmd);
- system(removecmd);
- sprintf(syscmd,"subimg temp1.rgb %s 0 %d 0 %d",outname,xsize-1,ysize-1);
- system(syscmd);
- sprintf(syscmd,"rm temp1.rgb");
- system(syscmd);
- }
- if(orthomode)
- ortho(ox1,ox2,oy1,oy2,oz1,oz2);
- else
- window(rl,rr,rb,rt,rnear,rfar);
- }
-
- static makename(n,name)
- int n;
- char *name;
- {
- sprintf(name,"temp%03d.rgb",n);
- }
-
- static makeframe(x,y,xdraw,ydraw,xsize,ysize)
- int x, y;
- int xdraw, ydraw;
- int xsize, ysize;
- {
- float l, r, b, t;
- float x1, x2, y1, y2;
- float vsize, hsize;
- float xrend, yrend;
-
- mmode(MPROJECTION);
- if(orthomode) {
- hsize = ox2-ox1;
- vsize = oy2-oy1;
- xrend = xdraw*(hsize/xsize);
- yrend = ydraw*(vsize/ysize);
- x1 = ox1+x*xrend;
- x2 = x1+xrend;
- y1 = oy1+y*yrend;
- y2 = y1+yrend;
- ortho(x1,x2,y1,y2,oz1,oz2);
- } else {
- vsize = (rt-rb);
- hsize = xsize*(vsize/ysize);
- xrend = xdraw*(hsize/xsize);
- yrend = ydraw*(vsize/ysize);
- l = x*xrend-hsize/2.0;
- r = l+xrend;
- b = y*yrend-vsize/2.0;
- t = b+yrend;
- window(l,r,b,t,rnear,rfar);
- }
- mmode(MVIEWING);
- }
-
- /*
- * general environment drawing stuff follows
- *
- *
- */
- rendercubetoscreen(drawfunc)
- int (*drawfunc)();
- {
- short x1, x2, y1, y2;
- int deltax, deltay;
- int xclick, yclick;
- int i;
-
- rgb(0.0,0.0,0.0);
- clear();
- pushviewport();
- getviewport(&x1,&x2,&y1,&y2);
- deltax = x2-x1;
- deltay = y2-y1;
- xclick = deltax/4;
- yclick = deltay/3;
- mmode(MPROJECTION);
- perspective(900,1.0/1.0,rnear,rfar);
- mmode(MVIEWING);
- if(glgetmode() & DOUBLEBUFFER)
- glsetmode(INHIBITSWAP,1);
- for(i=0; i<6; i++) {
- pushmatrix();
- switch(i) {
- case 0:
- setvp(1,1,x1,y1,xclick,yclick);
- rot(0.0,'y');
- break;
- case 1:
- setvp(2,1,x1,y1,xclick,yclick);
- rot(90.0,'y');
- break;
- case 2:
- setvp(3,1,x1,y1,xclick,yclick);
- rot(180.0,'y');
- break;
- case 3:
- setvp(0,1,x1,y1,xclick,yclick);
- rot(270.0,'y');
- break;
- case 4:
- setvp(1,2,x1,y1,xclick,yclick);
- rot(-90.0,'x');
- break;
- case 5:
- setvp(1,0,x1,y1,xclick,yclick);
- rot(90.0,'x');
- break;
- }
- (drawfunc)();
- popmatrix();
- }
- if(glgetmode() & DOUBLEBUFFER) {
- glsetmode(INHIBITSWAP,0);
- swapbuffers();
- }
- popviewport();
- }
-
- static setvp(xpos,ypos,xorg,yorg,xclick,yclick)
- int xpos,ypos,xorg,yorg,xclick,yclick;
- {
- int x1, x2, y1, y2;
-
- x1 = xorg+(xpos+0)*xclick;
- y1 = yorg+(ypos+0)*yclick;
- x2 = xorg+(xpos+1)*xclick;
- y2 = yorg+(ypos+1)*yclick;
- viewport(x1,x2-1,y1,y2-1);
- }
-
- rendercylinder(drawfunc,nsides)
- int (*drawfunc)();
- int nsides;
- {
- short x1, x2, y1, y2;
- float fx1, fx2, xclick;
- int deltax, deltay;
- int i;
- float angleper, angle, tangle;
-
- rgb(0.0,0.0,0.0);
- clear();
- pushviewport();
- getviewport(&x1,&x2,&y1,&y2);
- deltax = x2-x1+1;
- deltay = y2-y1+1;
- xclick = deltax/(float)nsides;
- angleper = (2.0*M_PI)/nsides;
- tangle = tan(angleper/2);
- angle = 2*(180.0*atan(tangle*deltay/xclick))/M_PI;
- if(glgetmode() & DOUBLEBUFFER)
- glsetmode(INHIBITSWAP,1);
- for(i=0; i<nsides; i++) {
- fx1 = x1+i*xclick+0.5;
- fx2 = x1+(i+1)*xclick+0.5;
- viewport((int)fx1,((int)fx2)-1,y1,y2);
- mmode(MPROJECTION);
- renderfperspective(angle,(float)xclick/deltay,rnear,rfar);
- rot(((i+0.5)*360.0)/nsides-90.0-45.0,'y');
- mmode(MVIEWING);
- pushmatrix();
- (drawfunc)();
- popmatrix();
- }
- if(glgetmode() & DOUBLEBUFFER) {
- glsetmode(INHIBITSWAP,0);
- swapbuffers();
- }
- popviewport();
- }
-
- renderfacestoscreen(drawfunc)
- int (*drawfunc)();
- {
- int i;
- char *fixcmd;
-
- mmode(MPROJECTION);
- perspective(900,1.0/1.0,rnear,rfar);
- mmode(MVIEWING);
- for(i=0; i<6; i++) {
- pushmatrix();
- switch(i) {
- case 0:
- rot(0.0,'y');
- break;
- case 1:
- rot(90.0,'y');
- break;
- case 2:
- rot(180.0,'y');
- break;
- case 3:
- rot(270.0,'y');
- break;
- case 4:
- rot(-90.0,'x');
- break;
- case 5:
- rot(90.0,'x');
- break;
- }
- (drawfunc)();
- popmatrix();
- }
- }
-
- renderenvtofile(drawfunc,filename)
- int (*drawfunc)();
- char *filename;
- {
- int i;
- char *savename;
- char *fixcmd;
- char cmdbuf[256];
-
- mmode(MPROJECTION);
- perspective(900,1.0/1.0,rnear,rfar);
- mmode(MVIEWING);
- for(i=0; i<6; i++) {
- pushmatrix();
- switch(i) {
- case 0:
- rot(0.0,'y');
- fixcmd = "mv Et.rgb Epx.rgb";
- break;
- case 1:
- rot(90.0,'y');
- fixcmd = "iflip Et.rgb Epy.rgb 270";
- break;
- case 2:
- rot(180.0,'y');
- fixcmd = "iflip Et.rgb Emx.rgb y";
- break;
- case 3:
- rot(270.0,'y');
- fixcmd = "iflip Et.rgb Emy.rgb xy";
- break;
- case 4:
- rot(-90.0,'x');
- fixcmd = "iflip Et.rgb Epz.rgb 90";
- break;
- case 5:
- rot(90.0,'x');
- fixcmd = "iflip Et.rgb Emz.rgb xy";
- break;
- }
- printf("before it\n");
- (drawfunc)();
- popmatrix();
- savergbwindow("Et.rgb");
- system(fixcmd);
- printf("after it\n");
- }
- sprintf(cmdbuf,"assemble 3 2 %s Emx.rgb Emy.rgb Emz.rgb Epx.rgb Epy.rgb Epz.rgb",filename);
- system(cmdbuf);
- system("rm Et.rgb Emx.rgb Emy.rgb Emz.rgb Epx.rgb Epy.rgb Epz.rgb");
- }
-
- /*
- * screen saving utilities
- *
- */
- savergbwindow(name)
- char *name;
- {
- long xsize, ysize;
-
- if(glgetmode()&DOUBLEBUFFER)
- readsource(SRC_FRONT);
- getsize(&xsize,&ysize);
- savergbrect(name,0,0,xsize-1,ysize-1);
- if(glgetmode()&DOUBLEBUFFER)
- readsource(SRC_BACK);
- }
-
- savergbrect(name,x1,y1,x2,y2)
- char *name;
- int x1, y1, x2, y2;
- {
- int xsize, ysize;
- int y;
- IMAGE *oimage;
- unsigned long *lbuf, *lptr;
- short *rbuf, *gbuf, *bbuf;
- int togo, maxrows, thistime;
-
- xsize = x2-x1+1;
- ysize = y2-y1+1;
- maxrows = 25000/xsize;
- lbuf = (unsigned long *)mymalloc(maxrows*xsize*sizeof(unsigned long));
- rbuf = (short *)mymalloc(xsize*sizeof(short));
- gbuf = (short *)mymalloc(xsize*sizeof(short));
- bbuf = (short *)mymalloc(xsize*sizeof(short));
- oimage = iopen(name,"w",RLE(1),3,xsize,ysize,3);
- if(!oimage) {
- fprintf(stderr,"savergbrect: can't open output file\n");
- exit(1);
- }
- togo = ysize;
- y = 0;
- while(togo) {
- thistime = togo;;
- if(thistime>maxrows)
- thistime = maxrows;
- lrectread(x1+0,y1+y,x1+xsize-1,y1+y+thistime-1,lbuf);
- togo -= thistime;
- lptr = lbuf;
- while(thistime--) {
- cpacktorgb(lptr,rbuf,gbuf,bbuf,xsize);
- putrow(oimage,rbuf,y,0);
- putrow(oimage,gbuf,y,1);
- putrow(oimage,bbuf,y,2);
- lptr += xsize;
- y++;
- }
- }
- iclose(oimage);
- free(lbuf);
- free(rbuf);
- free(gbuf);
- free(bbuf);
- }
-
- zoomrgbwindow(name,factor)
- char *name;
- int factor;
- {
- long xsize, ysize;
- int ixsize, iysize;
- int y;
- IMAGE *oimage;
- unsigned long *lbuf, *lptr;
- short *rbuf, *gbuf, *bbuf;
- int togo, maxrows, thistime;
-
- if(glgetmode()&DOUBLEBUFFER)
- readsource(SRC_FRONT);
-
- if(factor>11) {
- fprintf(stderr,"zoomrgbwindow: factor may not exceed 11\n");
- exit(1);
- }
- getsize(&xsize,&ysize);
- ixsize = xsize/factor;
- iysize = ysize/factor;
- xsize = ixsize*factor;
- ysize = iysize*factor;
- maxrows = 25000/xsize;
- lbuf = (unsigned long *)mymalloc(maxrows*xsize*sizeof(unsigned long));
- rbuf = (short *)mymalloc(ixsize*sizeof(short));
- gbuf = (short *)mymalloc(ixsize*sizeof(short));
- bbuf = (short *)mymalloc(ixsize*sizeof(short));
- oimage = iopen(name,"w",RLE(1),3,ixsize,iysize,3);
- if(!oimage) {
- fprintf(stderr,"zoomrgbwindow: can't open output file\n");
- exit(1);
- }
- togo = ysize;
- zerorow(rbuf,ixsize);
- zerorow(gbuf,ixsize);
- zerorow(bbuf,ixsize);
- y = 0;
- while(togo) {
- thistime = togo;;
- if(thistime>maxrows)
- thistime = maxrows;
- lrectread(0,y,xsize-1,y+thistime-1,lbuf);
- togo -= thistime;
- lptr = lbuf;
- while(thistime--) {
- zoomadd(lptr,rbuf,gbuf,bbuf,factor,xsize);
- lptr += xsize;
- y++;
- if((y%factor) == 0) {
- divrow(rbuf,rbuf,factor*factor,ixsize);
- divrow(gbuf,gbuf,factor*factor,ixsize);
- divrow(bbuf,bbuf,factor*factor,ixsize);
- putrow(oimage,rbuf,(y-1)/factor,0);
- putrow(oimage,gbuf,(y-1)/factor,1);
- putrow(oimage,bbuf,(y-1)/factor,2);
- zerorow(rbuf,ixsize);
- zerorow(gbuf,ixsize);
- zerorow(bbuf,ixsize);
- }
- }
- }
- iclose(oimage);
- if(glgetmode()&DOUBLEBUFFER)
- readsource(SRC_BACK);
- free(lbuf);
- free(rbuf);
- free(gbuf);
- free(bbuf);
- }
-
- static zoomadd(cptr,rbuf,gbuf,bbuf,factor,n)
- unsigned char *cptr;
- short *rbuf, *gbuf, *bbuf;
- int factor, n;
- {
- int f;
-
- f = factor;
- while(n--) {
- cptr++;
- *bbuf += cptr[0];
- *gbuf += cptr[1];
- *rbuf += cptr[2];
- cptr += 3;
- if(--f == 0) {
- f = factor;
- rbuf++;
- gbuf++;
- bbuf++;
- }
- }
- }
-
- /*
- * lbuftoimage -
- * do a filtered zoom on an array of longs into
- * an image file.
- *
- */
- static int gz;
- static IMAGE *gimage;
- static unsigned long *glbuf;
- static int gbxsize, gbysize;
-
- static ggetimgrow(buf,y)
- short *buf;
- int y;
- {
- unsigned long *lptr;
- int n, shift;
-
- lptr = glbuf+(y*gbxsize);
- shift = 8*gz;
- n = gbxsize;
- while(n--)
- *buf++ = ((*lptr++)>>shift)&0xff;
- }
-
- static gputimgrow(buf,y)
- short *buf;
- int y;
- {
- putrow(gimage,buf,y,gz);
- }
-
- lbuftoimage(lbuf,bxsize,bysize,name,ixsize,iysize,filter)
- unsigned long *lbuf;
- int bxsize, bysize;
- char *name;
- int ixsize, iysize, filter;
- {
- gimage = iopen(name,"w",RLE(1),3,ixsize,iysize,3);
- glbuf = lbuf;
- gbxsize = bxsize;
- gbysize = bysize;
- for(gz=0; gz<3; gz++)
- filterzoom(ggetimgrow,gputimgrow,bxsize,bysize,ixsize,iysize,filter,1.0);
- iclose(gimage);
- }
-